package experiment4;

/**
 * 求一段序列中，第k小的元素
 *
 * @author mazouri
 * @create 2021-11-04 10:44
 */
public class FindK {
    public static void main(String[] args) {
        int[] a = {3, 2, 7, 1, 2, 4, 5, 5, 6};
        int k = 4;
        System.out.println(select(a, k));
    }

    private static int select(int[] a, int k) {
        int lo = 0;
        int hi = a.length - 1;
        while (hi > lo) {
            int j = partition(a, lo, hi);
            if      (j == k)   return a[k];
            else if (j > k)    hi = j - 1;
            else               lo = j + 1;
        }
        return a[k];
    }

    private static int partition(int[] a, int lo, int hi) {
        int i = lo;
        int j = hi + 1;
        int v = a[lo];
        while (true) {
            while (a[++i] < v) if (i == hi) break;
            while (v < a[--j]) if (j == lo) break;
            if (i >= j) break;
            exch(a, i, j);
        }

        exch(a, lo, j);
        return j;
    }

    private static void exch(int[] a, int i, int j) {
        int swap = a[i];
        a[i] = a[j];
        a[j] = swap;
    }
}
